`include "../inc/uart.h"

module uart_tx (	
	input  wire				   clk,		
	input  wire				   nRST,		
	input  wire				   tx_start,
	input  wire [7:0] tx_data,
	output wire				   tx_busy,
	output reg				   tx_end,
	
	output reg				   tx		 
);

	reg [`UartStateBus]		   state;
	reg [`UartDivCntBus]	   div_cnt;
	reg [`UartBitCntBus]	   bit_cnt;
	reg [7:0]		   sh_reg;
	
	assign tx_busy = (state == `UART_STATE_TX) ? 1'b1 : 1'b0;
	
	always @(posedge clk or negedge nRST) begin
		if (!nRST) begin			
			state	<=   `UART_STATE_IDLE;
			div_cnt <=   `UART_DIV_RATE;
			bit_cnt <=   `UART_BIT_CNT_START;
			sh_reg	<=   8'h0;
			tx_end	<=   1'b0;
			tx		<=   `UART_STOP_BIT;
		end else begin
			case (state)
				`UART_STATE_IDLE : begin
					if (tx_start == 1'b1) begin
						state	<=   `UART_STATE_TX;
						sh_reg	<=   tx_data;
						tx		<=   `UART_START_BIT;
					end
					tx_end	<=   1'b0;
				end
				`UART_STATE_TX	 : begin
					
					if (div_cnt == {`UART_DIV_CNT_W{1'b0}}) begin
						case (bit_cnt)
							`UART_BIT_CNT_MSB  : begin
								bit_cnt <=   `UART_BIT_CNT_STOP;
								tx		<=   `UART_STOP_BIT;
							end
							`UART_BIT_CNT_STOP : begin
								state	<=   `UART_STATE_IDLE;
								bit_cnt <=   `UART_BIT_CNT_START;
								tx_end	<=   1'b1;
							end
							default			   : begin
								bit_cnt <=   bit_cnt + 1'b1;
								sh_reg	<=   sh_reg >> 1'b1;
								tx		<=   sh_reg[0];
							end
						endcase
						div_cnt <=   `UART_DIV_RATE;
					end else begin
						div_cnt <=   div_cnt - 1'b1 ;
					end
				end
			endcase
		end
	end

endmodule